CLASS ymoon_api DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    METHODS:constructor IMPORTING  i_scenario TYPE string
                                   i_service  TYPE string
                        EXCEPTIONS no_arrangement.

    METHODS:get_token_cookies RETURNING VALUE(token) TYPE string.

    METHODS:get IMPORTING uri        TYPE string
                RETURNING VALUE(res) TYPE string.

    METHODS:post IMPORTING json   TYPE string
                 EXPORTING body   TYPE string
                           status TYPE i.

    CLASS-METHODS: check_message IMPORTING json_str   TYPE string
                                           field      TYPE string
                                 RETURNING VALUE(msg) TYPE string.
    CLASS-METHODS: xml_to_abap IMPORTING xml_string       TYPE string
                                         append_component TYPE string
                               CHANGING  o_table             TYPE REF TO data.
  PROTECTED SECTION.
  PRIVATE SECTION.
    DATA: scenario TYPE if_com_management=>ty_cscn_id,
          service  TYPE if_com_management=>ty_cscn_outb_srv_id.
    DATA: ca TYPE REF TO if_com_arrangement .
    DATA: token   TYPE string,
          cookies TYPE if_web_http_request=>cookies.

    CONSTANTS:
      c_content_type TYPE string VALUE 'Content-type',
      c_json_content TYPE string VALUE 'application/json; charset=UTF-8'.
ENDCLASS.



CLASS YMOON_API IMPLEMENTATION.


  METHOD check_message.


*    DATA: g_js         TYPE REF TO cl_java_script,
*          g_javascript TYPE string,
*          g_return     TYPE string.
*
*    DATA(data_define) = `var e = ` &&  json_str && `;`.
*    DATA(if_str) = `if (obj.` && field && `) {`.
*    DATA(return_str) = `return obj.` && field && `;`.
*
*    CONCATENATE data_define
*      `function getValue(str) {`
*      `const obj = str`
*      if_str
*      return_str
*      `} else {`
*      `return null;`
*      `}`
*      `}`
*      `getValue(e);`
*      INTO g_javascript SEPARATED BY cl_abap_char_utilities=>cr_lf.
*
*
*    g_return = g_js->evaluate( g_javascript ).
  ENDMETHOD.


  METHOD constructor.
    me->scenario = i_scenario.
    me->service = i_service.

    "시나리오 이름으로 통신이 존재하는지 확인
    DATA: lr_cscn TYPE if_com_scenario_factory=>ty_query-cscn_id_range.
    lr_cscn = VALUE #( ( sign = 'I' option = 'EQ' low = me->scenario ) ).

    DATA(lo_factory) = cl_com_arrangement_factory=>create_instance( ).
    lo_factory->query_ca(
          EXPORTING
            is_query           = VALUE #( cscn_id_range = lr_cscn )
          IMPORTING
            et_com_arrangement = DATA(lt_ca)
        ).


    IF lt_ca IS NOT INITIAL.
      me->ca = lt_ca[ 1 ].
    ELSE.
      RAISE no_arrangement.
    ENDIF.


  ENDMETHOD.


  METHOD get.
    data:exref TYPE REF TO CX_ROOT.
    TRY.
        DATA(lo_dest) = cl_http_destination_provider=>create_by_comm_arrangement(
            comm_scenario  = me->scenario
            service_id     = me->service
            comm_system_id = me->ca->get_comm_system_id( ) ).
        DATA(lo_http_client) = cl_web_http_client_manager=>create_by_http_destination( lo_dest ).

        DATA(lo_request) = lo_http_client->get_http_request( ).
        lo_request->set_uri_path( EXPORTING i_uri_path = '?' && uri ).

        DATA(lo_response) = lo_http_client->execute( if_web_http_client=>get ).


        res   = lo_response->get_text( ).
      CATCH cx_http_dest_provider_error.
        " handle exception here

      CATCH cx_web_http_client_error into exref.
            data(error) = exref->GET_TEXT( ).
        " handle exception here
    ENDTRY.
  ENDMETHOD.


  METHOD get_token_cookies.
    "GET
    TRY.
        DATA(lo_dest) = cl_http_destination_provider=>create_by_comm_arrangement(
            comm_scenario  = me->scenario
            service_id     = me->service
            comm_system_id = me->ca->get_comm_system_id( ) ).
        DATA(lo_http_client) = cl_web_http_client_manager=>create_by_http_destination( lo_dest ).

        DATA(lo_request) = lo_http_client->get_http_request( ).
        lo_request->set_uri_path( EXPORTING i_uri_path = '?$top=1' ).
        lo_request->set_header_field( i_name = 'x-csrf-token' i_value = 'fetch' ).
        DATA(lo_response) = lo_http_client->execute( if_web_http_client=>get ).

        "get 해서, token이랑 cookie값 가져오기
        me->token = token  = lo_response->get_header_field( i_name = 'x-csrf-token' ).
        me->cookies = lo_response->get_cookies( ).

      CATCH cx_http_dest_provider_error.
        " handle exception here

      CATCH cx_web_http_client_error.
        " handle exception here
    ENDTRY.
  ENDMETHOD.


  METHOD post.
    "POST
    TRY.
        DATA(lo_dest) = cl_http_destination_provider=>create_by_comm_arrangement(
            comm_scenario  = me->scenario
            service_id     = me->service
            comm_system_id = me->ca->get_comm_system_id( ) ).
        DATA(lo_http_client) = cl_web_http_client_manager=>create_by_http_destination( lo_dest ).

        DATA(lo_request) = lo_http_client->get_http_request( ).

        "json body 설정
        lo_request->set_text( json ).
        "GET에서 가져왔던 cookie, token값 셋팅
        LOOP AT me->cookies INTO DATA(cookie).
          lo_request->set_cookie( i_name = cookie-name i_value = cookie-value ).
        ENDLOOP.

        lo_request->set_header_field( i_name = me->c_content_type   i_value = me->c_json_content ).
        lo_request->set_header_field( i_name = 'Accept' i_value = 'application/json' ).
        lo_request->set_header_field( i_name = 'x-csrf-token' i_value = me->token ).
        DATA(lo_response) = lo_http_client->execute( if_web_http_client=>post ).

        body   = lo_response->get_text( ).
        status = lo_response->get_status( )-code.

      CATCH cx_http_dest_provider_error.
        " handle exception here

      CATCH cx_web_http_client_error.
        " handle exception here
    ENDTRY.



  ENDMETHOD.


  METHOD xml_to_abap.
    DATA: lv_xstring         TYPE xstring.
    DATA: lv_reader          TYPE REF TO if_sxml_reader.
    DATA: lv_node            TYPE REF TO if_sxml_node.
    DATA: lv_open_node       TYPE REF TO if_sxml_open_element.
    DATA: lv_close_node      TYPE REF TO if_sxml_close_element.
    DATA: lv_value_node      TYPE REF TO if_sxml_value.
    DATA: lv_value           TYPE string.
    DATA:lv_field TYPE c LENGTH 20.
    FIELD-SYMBOLS <fs> TYPE any.

    lv_xstring = cl_abap_conv_codepage=>create_out( codepage = `UTF-8` )->convert( source = xml_string ).

    lv_reader = cl_sxml_string_reader=>create( lv_xstring ).
    lv_node = lv_reader->read_next_node( ).


    ASSERT lv_node IS NOT INITIAL.
    WHILE lv_reader->node_type <> if_sxml_node=>co_nt_final.
      CASE lv_reader->node_type.
        WHEN if_sxml_node=>co_nt_element_open.
          lv_open_node  ?= lv_node.

          lv_field = 'ls_data-' && lv_open_node->qname-name.

        WHEN if_sxml_node=>co_nt_element_close.
          lv_close_node ?= lv_node.

*          IF lv_close_node->qname-name = gv_cond.
*            APPEND ls_data TO lt_data.
*            CLEAR ls_data.
*          ELSE.
*            ASSIGN (gv_field) TO <fs>.
*            IF sy-subrc = 0.
*              <fs> = lv_value.
*            ENDIF.
*          ENDIF.

        WHEN if_sxml_node=>co_nt_value.
          lv_value_node ?= lv_node.
          lv_value = lv_value_node->get_value( ).
        WHEN if_sxml_node=>co_nt_attribute.
      ENDCASE.
      lv_node = lv_reader->read_next_node( ).
    ENDWHILE.

  ENDMETHOD.
ENDCLASS.
